﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace theguineasyndrome
{
    public class Camera
    {
        private Vector2 screenSize;
        private Vector2 position;
        private Rectangle rectangle;
        private Level level;
        private bool locked;

        public Camera(Vector2 screenSize, Level level)
        {
            this.screenSize = screenSize;
            this.level = level;
            this.locked = false;
            setPosition(new Vector2(0, 0));
        }

        public void setLocked(bool locked)
        {
            this.locked = locked;
        }

        public void toggleLock()
        {
            locked = !locked;
        }

        public void setCenter(Vector2 center)
        {
            setPosition(new Vector2(center.X - Width / 2, center.Y - Height / 2));
        }

        public void moveCenterTo(Vector2 destinationCenter)
        {
            Vector2 currentCenter = new Vector2(position.X + Width / 2, position.Y + Height / 2);
            Vector2 move = destinationCenter - currentCenter;

            float distance = move.Length();
            float cameraSpeed = 80;
            float slowDistance = 700;

            if (distance < slowDistance)
                cameraSpeed *= distance / slowDistance;

            if (distance > cameraSpeed)
            {
                move.Normalize();
                move *= cameraSpeed;
            }
            setCenter(currentCenter + move);
        }

        public void setPosition(Vector2 position)
        {
            if (!locked)
            {
                if (position.X < level.Left)
                    position.X = level.Left;

                else if (position.X > level.Right - Width)
                    position.X = level.Right - Width;

                if (position.Y < level.Top)
                    position.Y = level.Top;

                else if (position.Y > level.Bottom - Height)
                    position.Y = level.Bottom - Height;

                this.position = position;
                rectangle = new Rectangle((int)position.X, (int)position.Y, (int)screenSize.X, (int)screenSize.Y);
            }
        }

        public void setScreenSize(Vector2 screenSize)
        {
            this.screenSize = screenSize;
            rectangle = new Rectangle((int)position.X, (int)position.Y, (int)screenSize.X, (int)screenSize.Y);
        }

        public Vector2 getPosition()
        {
            return position;
        }

        public bool isVisible(Rectangle rectangle)
        {
            return !Rectangle.Intersect(rectangle, this.rectangle).IsEmpty;
        }

        public Rectangle getDstRect(Rectangle rectangle)
        {
            return new Rectangle((int)(rectangle.X - X), (int)(rectangle.Y - Y), (int)rectangle.Width, (int)rectangle.Height);
        }

        public Vector2 getDstPoint(Vector2 point)
        {
            return point - position;
        }

        public Vector2 getRelative(Vector2 mouse)
        {
            return mouse + position;
        }

        public float X
        {
            get { return position.X; }
        }

        public float Y
        {
            get { return position.Y; }
        }

        public float Width
        {
            get { return screenSize.X; }
        }

        public float Height
        {
            get { return screenSize.Y; }
        }

        public float Left
        {
            get { return position.X; }
        }

        public float Right
        {
            get { return position.X + screenSize.X; }
        }

        public float Top
        {
            get { return position.Y; }
        }

        public float Bottom
        {
            get { return position.Y + screenSize.Y; }
        }

        public void moveBy(Vector2 cameraMove)
        {
            setPosition(position + cameraMove);
        }

        public bool isInside(Vector2 point)
        {
            Vector2 relative = getRelative(point);
            return Left <= relative.X && relative.X <= Right && Top <= relative.Y && relative.Y <= Bottom;
        }
    }
}
